<template>
  <div v-if="show" class="preview-overlay" @click="closePreview">
    <div class="preview-modal" @click.stop>
      <!-- 预览头部 -->
      <div class="preview-header">
        <div class="preview-title">
          <span class="title-icon">📄</span>
          <h3>{{ document.kno_title }}</h3>
        </div>
        <div class="preview-actions">
          <button class="action-btn download-btn" @click="downloadDocument" title="下载文档">
            <span class="btn-icon">⬇</span>
            <span class="btn-text">下载</span>
          </button>
          <button class="action-btn close-btn" @click="closePreview" title="关闭预览">
            <span class="btn-icon">✕</span>
          </button>
        </div>
      </div>

      <!-- 预览内容区域 -->
      <div class="preview-content">
        <div v-if="loading" class="loading-container">
          <div class="loading-spinner"></div>
          <p>正在加载文档...</p>
        </div>
        
        <div v-else-if="error" class="error-container">
          <div class="error-icon">⚠️</div>
          <h3>预览失败</h3>
          <p>{{ error }}</p>
          <button class="retry-btn" @click="loadDocument">重试</button>
        </div>
        
        <div v-else class="document-viewer">
          <!-- Office文档预览 -->
          <div v-if="isOfficeDocument" class="office-viewer-container">
            <iframe 
              v-if="officeViewerUrl && !showDownloadOption"
              :src="officeViewerUrl" 
              class="office-viewer"
              frameborder="0"
              allowfullscreen
              @error="handleIframeError"
            ></iframe>
            <div v-if="loading && !showDownloadOption" class="office-loading">
              <div class="loading-spinner"></div>
              <p>正在加载文档预览...</p>
            </div>
            <div v-if="showDownloadOption || !officeViewerUrl" class="office-download-fallback">
              <div class="office-icon">
                <svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.89 22 5.99 22H18C19.1 22 20 21.1 20 20V8L14 2Z" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M14 2V8H20" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M16 13H8" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M16 17H8" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M10 9H9H8" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
              </div>
              <h3>{{ props.document.kno_title }}</h3>
              <p class="file-type">{{ fileExtension.toUpperCase() }} 文档</p>
              <p class="preview-tip">此文档类型暂不支持在线预览，请下载后在本地应用中打开</p>
              <div class="preview-actions">
                <button @click="downloadDocument" class="download-btn">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M21 15V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M7 10L12 15L17 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M12 15V3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  </svg>
                  下载文档
                </button>
                <button v-if="officeViewerUrl" @click="openInNewTab" class="open-btn">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M18 13V19C18 19.5304 17.7893 20.0391 17.4142 20.4142C17.0391 20.7893 16.5304 21 16 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V8C3 7.46957 3.21071 6.96086 3.58579 6.58579C3.96086 6.21071 4.46957 6 5 6H11" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M15 3H21V9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M10 14L21 3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  </svg>
                  新窗口打开
                </button>
              </div>
            </div>
          </div>
          
          <!-- PDF预览 -->
          <iframe 
            v-else-if="isPdf" 
            :src="pdfUrl" 
            class="pdf-viewer"
            frameborder="0"
          ></iframe>
          
          <!-- 图片预览 -->
          <div v-else-if="isImage" class="image-viewer">
            <img :src="imageUrl" :alt="document.kno_title" class="preview-image" />
          </div>
          
          <!-- 文本预览 -->
          <div v-else-if="isText" class="text-viewer">
            <pre class="text-content">{{ textContent }}</pre>
          </div>
          
          <!-- 不支持的文件类型 -->
          <div v-else class="unsupported-container">
            <div class="unsupported-icon">📄</div>
            <h3>不支持预览</h3>
            <p>该文件类型暂不支持在线预览</p>
            <p class="file-info">文件类型: {{ fileExtension }}</p>
            <button class="download-btn" @click="downloadDocument">
              <span class="btn-icon">⬇</span>
              <span class="btn-text">下载查看</span>
            </button>
          </div>
        </div>
      </div>

      <!-- 预览底部信息 -->
      <div class="preview-footer">
        <div class="document-info">
          <span class="info-item">
            <span class="info-label">分类:</span>
            <span class="info-value">{{ document.kno_type }}</span>
          </span>
          <span class="info-item">
            <span class="info-label">作者:</span>
            <span class="info-value">{{ document.kno_authid }}</span>
          </span>
          <span class="info-item">
            <span class="info-label">创建时间:</span>
            <span class="info-value">{{ formatDateTime(document.kno_createtime) }}</span>
          </span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { getKnowledge, getKnowledgePreviewUrl } from '@/api/knowledge'

// Props
const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  document: {
    type: Object,
    default: () => ({})
  }
})

// Emits
const emit = defineEmits(['close'])

// 响应式数据
const loading = ref(false)
const error = ref('')
const textContent = ref('')
const documentUrl = ref('')
const documentData = ref(null)
const showDownloadOption = ref(false)
const detectedFileType = ref('')

// 从文件内容检测文件类型
const detectFileTypeFromContent = (base64Content) => {
  try {
    const binaryString = atob(base64Content)
    const bytes = new Uint8Array(binaryString.length)
    for (let i = 0; i < binaryString.length; i++) {
      bytes[i] = binaryString.charCodeAt(i)
    }
    
    // 检查文件头（魔数）
    if (bytes.length >= 4) {
      // PDF文件头: %PDF
      if (bytes[0] === 0x25 && bytes[1] === 0x50 && bytes[2] === 0x44 && bytes[3] === 0x46) {
        return 'pdf'
      }
      
      // ZIP文件头（DOCX, XLSX, PPTX都是ZIP格式）
      if (bytes[0] === 0x50 && bytes[1] === 0x4B) {
        // 需要进一步检查ZIP内容来确定具体类型
        return 'zip-based-office'
      }
      
      // PNG文件头
      if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47) {
        return 'png'
      }
      
      // JPEG文件头
      if (bytes[0] === 0xFF && bytes[1] === 0xD8) {
        return 'jpg'
      }
      
      // GIF文件头
      if (bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46) {
        return 'gif'
      }
    }
  } catch (err) {
    console.warn('文件类型检测失败:', err)
  }
  
  return null
}

// 计算属性
const fileExtension = computed(() => {
  // 优先使用检测到的文件类型
  if (detectedFileType.value) {
    return detectedFileType.value
  }
  
  if (!props.document?.kno_title) return ''
  
  // 首先尝试从标题中提取扩展名
  const lastDotIndex = props.document.kno_title.lastIndexOf('.')
  if (lastDotIndex !== -1) {
    const ext = props.document.kno_title.substring(lastDotIndex + 1).toLowerCase()
    // 验证扩展名是否有效
    const validExtensions = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'md', 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
    if (validExtensions.includes(ext)) {
      return ext
    }
  }
  
  // 如果没有扩展名，尝试从kno_type字段推断
  if (props.document?.kno_type) {
    const typeLower = props.document.kno_type.toLowerCase()
    if (typeLower.includes('word') || typeLower.includes('doc')) return 'docx'
    if (typeLower.includes('excel') || typeLower.includes('xls')) return 'xlsx'
    if (typeLower.includes('powerpoint') || typeLower.includes('ppt')) return 'pptx'
    if (typeLower.includes('pdf')) return 'pdf'
    if (typeLower.includes('image') || typeLower.includes('img')) return 'jpg'
    if (typeLower.includes('text') || typeLower.includes('txt')) return 'txt'
  }
  
  // 如果都没有，返回空字符串
  return ''
})

const isOfficeDocument = computed(() => {
  const officeExtensions = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'zip-based-office']
  return officeExtensions.includes(fileExtension.value)
})

const isPdf = computed(() => {
  return fileExtension.value === 'pdf'
})

const isImage = computed(() => {
  const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  return imageExtensions.includes(fileExtension.value)
})

const isText = computed(() => {
  const textExtensions = ['txt', 'md', 'json', 'xml', 'html', 'css', 'js', 'py', 'java', 'cpp', 'c']
  return textExtensions.includes(fileExtension.value)
})

const officeViewerUrl = computed(() => {
  if (!props.document?.kno_id) return ''
  
  // 对于Office文档，尝试使用Microsoft Office Online Viewer
  // 如果后端有专门的预览服务，使用后端接口
  // 否则使用Microsoft Office Online Viewer
  const baseUrl = getKnowledgePreviewUrl(props.document.kno_id)
  
  // 检查是否是有效的预览URL
  if (baseUrl && !baseUrl.includes('data:')) {
    return baseUrl
  }
  
  // 如果没有有效的预览URL，返回空字符串，将显示下载选项
  return ''
})

const pdfUrl = computed(() => {
  if (!documentData.value?.kno_url) return ''
  return `data:application/pdf;base64,${documentData.value.kno_url}`
})

const imageUrl = computed(() => {
  if (!documentData.value?.kno_url) return ''
  return `data:image/${fileExtension.value};base64,${documentData.value.kno_url}`
})

// 方法
const closePreview = () => {
  emit('close')
}

const loadDocument = async () => {
  if (!props.document.kno_id) {
    error.value = '文档ID不存在'
    return
  }

  loading.value = true
  error.value = ''
  showDownloadOption.value = false

  try {
    // 根据ID查询文档详情
    const response = await getKnowledge(props.document.kno_id)
    
    if (response.code === 200 && response.data) {
      documentData.value = response.data
      
      // 检测文件类型
      if (response.data.kno_url) {
        const detectedType = detectFileTypeFromContent(response.data.kno_url)
        if (detectedType) {
          detectedFileType.value = detectedType
          console.log('检测到文件类型:', detectedType)
        }
      }
      
      if (isOfficeDocument.value) {
        // 对于Office文档，检查是否有有效的预览URL
        const previewUrl = getKnowledgePreviewUrl(props.document.kno_id)
        if (!previewUrl || previewUrl.includes('data:')) {
          // 如果没有有效的预览URL，显示下载选项
          showDownloadOption.value = true
        }
      } else if (isPdf.value) {
        // PDF文档直接使用base64
      } else if (isImage.value) {
        // 图片文档直接使用base64
      } else if (isText.value) {
        // 解码Base64文本内容
        try {
          const decodedContent = atob(response.data.kno_url)
          textContent.value = decodedContent
        } catch (decodeError) {
          console.error('解码文本内容失败:', decodeError)
          error.value = '文档内容解码失败'
        }
      }
    } else {
      error.value = response.message || '获取文档失败'
    }
  } catch (err) {
    console.error('加载文档失败:', err)
    error.value = '网络错误，请重试'
  } finally {
    loading.value = false
  }
}


const handleIframeError = () => {
  console.warn('Office文档预览失败，显示下载选项')
  showDownloadOption.value = true
  loading.value = false
}

const openInNewTab = () => {
  if (!props.document?.kno_id) return
  const previewUrl = getKnowledgePreviewUrl(props.document.kno_id)
  window.open(previewUrl, '_blank')
}

const downloadDocument = () => {
  try {
    if (!documentData.value?.kno_url) {
      error.value = '文档内容为空，无法下载'
      return
    }

    // 根据文件类型确定MIME类型
    let mimeType = 'application/octet-stream'
    
    if (isPdf.value) {
      mimeType = 'application/pdf'
    } else if (isImage.value) {
      mimeType = `image/${fileExtension.value}`
    } else if (isText.value) {
      mimeType = 'text/plain'
    } else if (isOfficeDocument.value) {
      switch (fileExtension.value) {
        case 'doc':
          mimeType = 'application/msword'
          break
        case 'docx':
          mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
          break
        case 'xls':
          mimeType = 'application/vnd.ms-excel'
          break
        case 'xlsx':
          mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
          break
        case 'ppt':
          mimeType = 'application/vnd.ms-powerpoint'
          break
        case 'pptx':
          mimeType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
          break
      }
    }

    // 验证base64数据
    try {
      const binaryString = atob(documentData.value.kno_url)
      const bytes = new Uint8Array(binaryString.length)
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i)
      }

      // 创建下载链接
      const blob = new Blob([bytes], { type: mimeType })
      const url = URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = props.document.kno_title || 'document'
      link.style.display = 'none'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
      
      console.log('文档下载成功:', props.document.kno_title)
    } catch (decodeError) {
      console.error('Base64解码失败:', decodeError)
      error.value = '文档格式错误，无法下载'
    }
  } catch (err) {
    console.error('下载失败:', err)
    error.value = '下载失败，请重试'
  }
}

const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  const date = new Date(dateTime)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 监听文档变化
watch(() => props.document, () => {
  if (props.show && props.document.kno_id) {
    loadDocument()
  }
}, { immediate: true })

// 监听显示状态
watch(() => props.show, (newVal) => {
  if (newVal && props.document.kno_id) {
    loadDocument()
  }
})

// 组件卸载时清理URL
onMounted(() => {
  return () => {
    if (documentUrl.value) {
      URL.revokeObjectURL(documentUrl.value)
    }
  }
})
</script>

<style scoped>
.preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 1rem;
}

.preview-modal {
  background: white;
  border-radius: 0.75rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  width: 90%;
  max-width: 1200px;
  height: 90%;
  max-height: 800px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
}

.preview-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.title-icon {
  font-size: 1.5rem;
}

.preview-title h3 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: #111827;
}

.preview-actions {
  display: flex;
  gap: 0.5rem;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.download-btn {
  background: #3b82f6;
  color: white;
}

.download-btn:hover {
  background: #2563eb;
}

.close-btn {
  background: #6b7280;
  color: white;
}

.close-btn:hover {
  background: #4b5563;
}

.preview-content {
  flex: 1;
  overflow: hidden;
  position: relative;
}

.loading-container,
.error-container,
.unsupported-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: 2rem;
}

.loading-spinner {
  width: 2rem;
  height: 2rem;
  border: 3px solid #e5e7eb;
  border-top: 3px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 1rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Office文档预览样式 */
.office-viewer-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.office-viewer {
  width: 100%;
  height: 100%;
  border: none;
}

.office-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #64748b;
  background: rgba(255, 255, 255, 0.9);
  padding: 20px;
  border-radius: 8px;
}

.office-loading .loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid #e2e8f0;
  border-top: 3px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

.office-download-fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: 2rem;
  background: #f9fafb;
}

.office-icon {
  margin-bottom: 1.5rem;
  opacity: 0.8;
}

.office-download-fallback h3 {
  margin: 0 0 0.5rem 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: #111827;
}

.file-type {
  margin: 0 0 1rem 0;
  font-size: 0.875rem;
  color: #6b7280;
  font-weight: 500;
}

.preview-tip {
  margin: 0 0 2rem 0;
  color: #6b7280;
  font-size: 0.875rem;
  line-height: 1.5;
  max-width: 400px;
}

.preview-actions {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}

.open-btn {
  background: #10b981;
  color: white;
  border: none;
  border-radius: 0.5rem;
  padding: 0.75rem 1.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.open-btn:hover {
  background: #059669;
}

.error-icon,
.unsupported-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
}

.error-container h3,
.unsupported-container h3 {
  margin: 0 0 0.5rem 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: #111827;
}

.error-container p,
.unsupported-container p {
  margin: 0 0 1rem 0;
  color: #6b7280;
}

.file-info {
  font-size: 0.875rem;
  color: #9ca3af;
}

.retry-btn,
.download-btn {
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 0.5rem;
  padding: 0.75rem 1.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s ease;
}

.retry-btn:hover,
.download-btn:hover {
  background: #2563eb;
}

.document-viewer {
  height: 100%;
  overflow: hidden;
}

.office-viewer,
.pdf-viewer {
  width: 100%;
  height: 100%;
  border: none;
}

.image-viewer {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f9fafb;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.text-viewer {
  height: 100%;
  overflow: auto;
  padding: 1rem;
  background: #f9fafb;
}

.text-content {
  background: white;
  padding: 1.5rem;
  border-radius: 0.5rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 0.875rem;
  line-height: 1.5;
  color: #374151;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
}

.preview-footer {
  padding: 1rem 1.5rem;
  border-top: 1px solid #e5e7eb;
  background: #f9fafb;
}

.document-info {
  display: flex;
  gap: 2rem;
  font-size: 0.875rem;
}

.info-item {
  display: flex;
  gap: 0.5rem;
}

.info-label {
  color: #6b7280;
  font-weight: 500;
}

.info-value {
  color: #111827;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .preview-modal {
    width: 95%;
    height: 95%;
  }
  
  .preview-header {
    padding: 0.75rem 1rem;
  }
  
  .preview-title h3 {
    font-size: 1rem;
  }
  
  .action-btn {
    padding: 0.5rem;
  }
  
  .btn-text {
    display: none;
  }
  
  .document-info {
    flex-direction: column;
    gap: 0.5rem;
  }
}
</style>